package com.org.oracle.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.org.oracle.mapper.UniversityMapper;
import com.org.oracle.mapper.UniversityScoreDistributionMapper;
import com.org.oracle.mapper.UniversityScoreLineMapper;
import com.org.oracle.mysql.dto.FindRangeSearchDTO;
import com.org.oracle.mysql.dto.FindSchoolSearchDTO;
import com.org.oracle.mysql.entity.University;
import com.org.oracle.mysql.entity.UniversityScoreDistribution;
import com.org.oracle.mysql.entity.UniversityScoreLine;
import com.org.oracle.mysql.vo.FindRangeSearchVO;
import com.org.oracle.mysql.vo.UniversityScoreDistributionVO;
import com.org.oracle.service.UniversityService;
import jakarta.annotation.Resource;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

/**
 * @author suze
 * @date 2024/11/30
 * @time 15:43
 **/
@Service
public class UniversityServiceImpl extends ServiceImpl<UniversityMapper, University> implements UniversityService {

    @Resource
    private UniversityMapper universityMapper;


    @Resource
    private UniversityScoreLineMapper universityScoreLineMapper;
    @Resource
    private UniversityScoreDistributionMapper universityScoreDistributionMapper;

/**
 * 根据筛选条件查找范围搜索信息
 * 此方法用于根据用户提供的筛选条件，查询符合条件的大学分数线信息，并将其转换为指定的VO列表返回
 *
 * @param findRangeSearchDTO 筛选条件封装对象，包含分页信息、地区、二级专业、三级专业和大学层次等条件
 * @return 返回一个FindRangeSearchVO对象的列表，如果查询结果为空或发生错误，则返回null
 */
@Override
public List<FindRangeSearchVO> findRangeSearch(FindRangeSearchDTO findRangeSearchDTO) {
    // 如果哪个条件为空的话 就默认是不筛选

    List<UniversityScoreLine> universityScoreLineList = universityScoreLineMapper.findRangeSearch(
            new Page<>(findRangeSearchDTO.getPage(), findRangeSearchDTO.getSize()),
            findRangeSearchDTO.getRegion()
            , findRangeSearchDTO.getSecondaryMajor()
            , findRangeSearchDTO.getTertiaryMajor()
    );
    if (universityScoreLineList == null)
        return null;
    //将大学分数线列表转换为FindRangeSearchVO列表
    return convertToFindRangeSearchVOList(universityScoreLineList);
}



    /**
     * 根据学校名称查找该校所有专业的分数线信息
     *
     * @param findSchoolSearchDTO 包含搜索学校所需信息的数据传输对象，包括页码和每页大小
     * @return 返回一个包含学校所有专业分数线信息的FindRangeSearchVO对象列表
     */
    @Override
    public List<FindRangeSearchVO> findSchool(FindSchoolSearchDTO findSchoolSearchDTO) {
        //这里搜索是按照学校来搜索该学校的所有专业的
        //相当于返回的就是该学校所有的学院所有的专业的分数线（里面又包含了分数分布情况）
        List<UniversityScoreLine> universityScoreLineList = universityScoreLineMapper.findBySchool(new Page<>(findSchoolSearchDTO.getPage(), findSchoolSearchDTO.getSize())
                , findSchoolSearchDTO.getSchool());
        //检查查询结果是否为空
        if (universityScoreLineList == null)
            return null;
        //将大学分数线列表转换为FindRangeSearchVO列表
        return convertToFindRangeSearchVOList(universityScoreLineList);
    }







    /**
     * 根据大学分数线信息获取分数分布视图对象列表
     *
     * 此方法通过查询数据库中与给定大学分数线相关的分数分布数据，并将其封装到视图对象（VO）列表中，
     * 以便于后续处理或展示这些数据
     *
     * @param universityScoreLine 大学分数线对象，包含查询所需的具体信息如学校、学院、次专业、三级专业等
     * @return 返回一个包含分数分布视图对象的列表，每个视图对象对应数据库中的一条分数分布记录
     */
    private List<UniversityScoreDistributionVO> getUniversityScoreDistributionVOsByLine(UniversityScoreLine universityScoreLine) {
        // 1. 查分数分布的 Mapper 得到一个初始的 List
        // 根据传入的大学分数线信息查询相关的分数分布数据
        List<UniversityScoreDistribution> universityScoreDistributionList =
                universityScoreDistributionMapper.findByFields(
                        universityScoreLine.getSchool().trim(),
                        universityScoreLine.getFaculty(),
                        universityScoreLine.getSecondaryMajor(),
                        universityScoreLine.getTertiaryMajor()
                );
        // 2. 处理这个 List
        // 将查询到的分数分布数据列表转换为视图对象列表，便于后续使用
        List<UniversityScoreDistributionVO> universityScoreDistributionVOS = universityScoreDistributionList.stream()
                .map(universityScoreDistribution -> {
                    UniversityScoreDistributionVO universityScoreDistributionVO = new UniversityScoreDistributionVO();
                    // 把查询出来的分数分布情况封装到 VO 中
                    BeanUtils.copyProperties(universityScoreDistribution, universityScoreDistributionVO);
                    return universityScoreDistributionVO;
                })
                .collect(Collectors.toList());

        return universityScoreDistributionVOS;
    }


    /**
     * 将大学分数线列表转换为FindRangeSearchVO列表
     * 此方法主要用于将包含大学分数线信息的对象列表，转换为另一个具有相同信息但结构不同的对象列表
     * 主要涉及对象属性的拷贝和集合的转换操作
     *
     * @param universityScoreLineList 大学分数线列表，包含多个UniversityScoreLine对象
     * @return 返回一个FindRangeSearchVO列表，每个对象对应于输入列表中的UniversityScoreLine对象
     */
    private List<FindRangeSearchVO> convertToFindRangeSearchVOList(List<UniversityScoreLine> universityScoreLineList) {
        //差一个图片搜索和转换
        // 使用Java 8的Stream API来转换列表中的每个UniversityScoreLine对象
        return universityScoreLineList.stream()
                .map(universityScoreLine -> {
                    // 创建一个新的FindRangeSearchVO对象来存储转换后的数据
                    FindRangeSearchVO findRangeSearchVO = new FindRangeSearchVO();
                    universityScoreLine.setSchool(universityScoreLine.getSchool().trim());
                    // 使用Spring框架的BeanUtils工具类来拷贝属性，简化数据转换过程
                    BeanUtils.copyProperties(universityScoreLine, findRangeSearchVO);
                    // 设置转换后的对象的大学分数分布信息
                    //TODO 院校分数分布的数据有问题  等暑假手动去做处理吧
                    //findRangeSearchVO.setUniversityScoreDistributionVOS(getUniversityScoreDistributionVOsByLine(universityScoreLine));
                    //现在只能先弄个假的用来演示了
                    findRangeSearchVO.setUniversityScoreDistributionVOS(TestDistributioin(universityScoreLine.getMinScore(),universityScoreLine.getMaxScore(),universityScoreLine.getEnrollment()));
                    findRangeSearchVO.setImg(universityMapper
                            .selectOne(Wrappers
                                    .<University>lambdaQuery()
                                    .eq(University::getSchool_name, universityScoreLine.getSchool().trim()))
                            .getImg());
                    // 返回转换后的对象

                    return findRangeSearchVO;
                })
                // 将转换后的流收集为列表
                .collect(Collectors.toList());
    }

    public List<UniversityScoreDistributionVO> TestDistributioin(String min, String max, String enrollment) {
        int minValue = Integer.parseInt(min);
        int maxValue = Integer.parseInt(max);
        int totalEnrollment = Integer.parseInt(enrollment);
        int INTERVAL = 20;

        List<UniversityScoreDistributionVO> universityScoreDistributionVOS = new ArrayList<>();
        Random random = new Random();

        // Generate score ranges
        for (int i = minValue; i <= maxValue; i += INTERVAL) {
            int currentMax = Math.min(i + INTERVAL - 1, maxValue);
            String scoreRange = i + "-" + currentMax;
            universityScoreDistributionVOS.add(new UniversityScoreDistributionVO(scoreRange, "0"));
        }

        // Assign random number of students to each score range
        int remainingEnrollment = totalEnrollment;
        int size = universityScoreDistributionVOS.size();

        for (int i = 0; i < size; i++) {
            int numberOfStudents;
            if (i == size - 1) {
                numberOfStudents = remainingEnrollment;
            } else {
                // Ensure at least 1 student per score range
                int maxPossible = remainingEnrollment - (size - i - 1); // Ensure remaining ranges can have at least 1 student
                numberOfStudents = 1 + random.nextInt(maxPossible);
                remainingEnrollment -= numberOfStudents;
            }
            universityScoreDistributionVOS.get(i).setNumberOfStudents(String.valueOf(numberOfStudents));
        }

        return universityScoreDistributionVOS;
        }
    }

